#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2024/9/20 18:01
# @Author  : Tom_zc
# @FileName: common.py
# @Software: PyCharm
import os
import sys
import time
import logging
import stat
import subprocess
import traceback
from functools import wraps

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s  %(levelname)s:%(message)s")


def execute_cmd3(cmd, timeout=30, err_log=True):
    """execute cmd"""
    try:
        logging.info("execute_cmd3 call cmd: %s" % cmd)
        p = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True, close_fds=True)
        t_wait_seconds = 0
        while True:
            if p.poll() is not None:
                break
            if timeout >= 0 and t_wait_seconds >= (timeout * 100):
                p.terminate()
                return -1, "", "execute_cmd3 exceeded time {0} seconds in executing: {1}".format(timeout, cmd)
            time.sleep(0.01)
            t_wait_seconds += 1
        out, err = p.communicate()
        ret = p.returncode
        if ret != 0 and err_log:
            logging.info("execute_cmd3 cmd {} return {}, std output: {}, err output: {}.".format(cmd, ret, out, err))
        return ret, out, err
    except Exception as e:
        return -1, "", "execute_cmd3 exceeded raise, e={0}, trace={1}".format(e.args[0], traceback.format_exc())


def func_retry(tries=3, delay=1):
    def deco_retry(fn):
        @wraps(fn)
        def inner(*args, **kwargs):
            for i in range(tries):
                try:
                    return fn(*args, **kwargs)
                except Exception as e:
                    logging.info("err:{}, traceback:{}".format(e, traceback.format_exc()))
                    time.sleep(delay)
            else:
                logging.info("func_retry: {} failed".format(fn.__name__))
                raise Exception("func_retry: {} failed".format(fn.__name__))

        return inner

    return deco_retry


def write_content(path, content, model="wb"):
    """write content to local"""
    flags = os.O_CREAT | os.O_WRONLY
    modes = stat.S_IWUSR | stat.S_IRUSR
    with os.fdopen(os.open(path, flags, modes), model) as f:
        result = f.write(content)
    return result
